import 'dart:convert';
import 'dart:io';

import 'package:fixnum/fixnum.dart';
import 'package:flutter/cupertino.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:get/get.dart';
import 'package:im_demo/app/services/websocket_service_protobuf.dart';
import 'package:im_demo/core/protos/message.pb.dart';
import '../../../../core/protos/v1/chat.pb.dart' as chat_proto;

import '../../../../utils/logger_util.dart';
import '../../../data/chat/convert_user_id.dart';

class GroupChatProtobufController extends GetxController {
  var editTextController = TextEditingController();
  var urlEditTextController = TextEditingController();
  var tokenEditTextController = TextEditingController();

  var userIdEditTextController = TextEditingController();
  var targetGroupIdEditTextController = TextEditingController();

  final messageList = <ChatMessage>[].obs;
  final inputText = ''.obs;

  static const defaultUrl = 'ws://192.168.1.100:8090/ws';
  static const token = '';

  var sendMessageText = '';

  @override
  void onInit() {
    super.onInit();
    editTextController.addListener(() {});
    Get.put(WebSocketServiceProtobuf());

    // _connectWebsocket();
  }

  @override
  void onReady() {
    super.onReady();

    updateUrlInputText(defaultUrl);
  }

  @override
  void onClose() {
    _disconnectWebsocket();
    super.onClose();
  }

  void updateInputText(String text) {
    editTextController.text = text;
  }

  void cleanInputText() {
    editTextController.clear();
  }

  void updateUrlInputText(String text) {
    urlEditTextController.text = text;
  }

  void cleanUrlInputText() {
    urlEditTextController.clear();
  }

  void updateTokenInputText(String text) {
    tokenEditTextController.text = text;
  }

  void cleanTokenInputText() {
    tokenEditTextController.clear();
  }

  void updateUserIdInputText(String text) {
    userIdEditTextController.text = text;
  }

  void cleanUserIdInputText() {
    userIdEditTextController.clear();
  }

  void updateTargetGroupIdInputText(String text) {
    targetGroupIdEditTextController.text = text;
  }

  void cleanTargetGroupIdInputText() {
    targetGroupIdEditTextController.clear();
  }

  void connectWebsocket() {
    _connectWebsocket();
  }

  void _connectWebsocket() async {
    final startConnectMessage =
        ChatMessage()
          ..type = MessageType.UNKNOWN
          ..token = ''
          ..sender = Int64.parseInt('-1')
          ..receiver = Int64.parseInt('-1')
          ..groupId = Int64.parseInt('-1')
          ..content = '开始连接,请稍等...';

    _addMessage(startConnectMessage);

    final url =
        urlEditTextController.text.isEmpty
            ? defaultUrl
            : urlEditTextController.text;
    logE('_connectWebsocket url:$url');

    await WebSocketServiceProtobuf.to.connect(url, token);

    if (WebSocketServiceProtobuf.to.isConnected.value) {
      final connectMessage =
          ChatMessage()
            ..type = MessageType.UNKNOWN
            ..token = ''
            ..sender = Int64.parseInt('-1')
            ..receiver = Int64.parseInt('-1')
            ..groupId = Int64.parseInt('-1')
            ..content = '已连接';

      _addMessage(connectMessage);
    }

    _setupWebSocket();
  }

  void disconnectWebsocket() {
    _disconnectWebsocket();
  }

  void _disconnectWebsocket() {
    WebSocketServiceProtobuf.to.disconnect();

    final message =
        ChatMessage()
          ..type = MessageType.UNKNOWN
          ..token = ''
          ..sender = Int64.parseInt('-1')
          ..receiver = Int64.parseInt('-1')
          ..groupId = Int64.parseInt('-1')
          ..content = '已断开连接';
    _addMessage(message);
  }

  void _setupWebSocket() {
    WebSocketServiceProtobuf.to.stream.listen(
      (data) {
        logE('_setupWebSocket()-->data:$data');

        MessageWrapper messageWrapper = MessageWrapper.fromBuffer(data);
        logE('_setupWebSocket()-->messageWrapper:$messageWrapper');

        // final responseMessage =
        //     ChatMessage()
        //       ..type = MessageType.UNKNOWN
        //       ..token = ''
        //       ..sender = Int64.parseInt('-1')
        //       ..receiver = Int64.parseInt('-1')
        //       ..groupId = Int64.parseInt('-1')
        //       ..content = data;
        //
        // _addMessage(responseMessage);

        handlerMessage(messageWrapper);
      },
      onDone: () => _disconnectWebsocket(),
      onError: (err) {
        logE('_setupWebSocket()-->onError:$err');

        _disconnectWebsocket();
      },
    );
  }

  void handlerMessage(MessageWrapper messageWrapper) {
    final sender = userIdEditTextController.text;
    final receiver = targetGroupIdEditTextController.text;

    final senderInt = Int64.parseInt(convertUserIdByUserName(sender));
    final receiverInt = Int64.parseInt(receiver);

    switch (messageWrapper.type) {
      case MessageType.REGISTER:
        break;
      case MessageType.LOGIN:
        // LoginResponse loginResponse = LoginResponse.fromBuffer(
        //   messageWrapper.payload,
        // );

        final chat_proto.Response loginResponse = chat_proto
            .Response.fromBuffer(messageWrapper.payload);

        final loginStatusStr = loginResponse.success ? '登录成功' : '登录失败';

        final loginMessage = ChatMessage(
          type: MessageType.LOGIN,
          token: '',
          sender: senderInt,
          receiver: receiverInt,
          content: loginStatusStr,
        );

        _addMessage(loginMessage);

        break;
      case MessageType.LOGOUT:
        break;
      case MessageType.PRIVATE_CHAT:
        break;
      case MessageType.GROUP_CHAT:
        // GroupChatResponse groupChatResponse = GroupChatResponse.fromBuffer(
        //   messageWrapper.payload,
        // );

        final chat_proto.Response groupChatResponse = chat_proto
            .Response.fromBuffer(messageWrapper.payload);

        logE('handlerMessage()-->groupChatResponse:$groupChatResponse');

        if (groupChatResponse.message == sendMessageText ||
            groupChatResponse.message == '消息发送成功') {
          return;
        }

        final responseContent = '接收：${groupChatResponse.message}';

        final groupChatMessage = ChatMessage(
          type: MessageType.GROUP_CHAT,
          token: '',
          sender: senderInt,
          receiver: receiverInt,
          content: responseContent,
        );

        _addMessage(groupChatMessage);
        break;
      default:
        break;
    }
  }

  void login() {
    if (userIdEditTextController.text.isEmpty) {
      Get.snackbar('温馨提示', '请输入UserId');
      return;
    }

    if (targetGroupIdEditTextController.text.isEmpty) {
      Get.snackbar('温馨提示', '请输入TargetGroupId');
      return;
    }

    final userId = userIdEditTextController.text;
    final targetGroupId = targetGroupIdEditTextController.text;

    final loginRequest = LoginRequest(
      username: userId,
      password: '',
      token: '',
      deviceId: '',
    );

    logE('_login()->loginRequest:$loginRequest');

    // final loginMessage =
    //     ChatMessage()
    //       ..type = MessageType.LOGIN
    //       ..token = ''
    //       ..sender = Int64.parseInt(_convertUserIdByUserName(userId))
    //       ..receiver = Int64.parseInt(targetUserId)
    //       ..groupId = Int64.parseInt('-1')
    //       ..content = loginRequest.writeToJson();
    //
    // logE('_login()->message:${loginMessage.writeToBuffer()}');

    final loginWrapper =
        MessageWrapper()
          ..type = MessageType.LOGIN
          ..payload = loginRequest.writeToBuffer();

    final send = loginWrapper.writeToBuffer();
    logE('_login()->message:$send');

    WebSocketServiceProtobuf.to.sendMessage(send);
  }

  void _addMessage(ChatMessage message) {
    messageList.insert(0, message);
  }

  void sendMessage(String text) {
    if (text.isEmpty) {
      if (Platform.isAndroid || Platform.isIOS) {
        Fluttertoast.showToast(msg: '请输入发送内容', gravity: ToastGravity.CENTER);
      } else {
        Get.snackbar('温馨提示', '请输入发送内容');
      }
      return;
    }

    final userId = userIdEditTextController.text;
    final targetGroupId = targetGroupIdEditTextController.text;

    final userIdInt = Int64.parseInt(convertUserIdByUserName(userId));
    final targetGroupIdInt = Int64.parseInt(targetGroupId);

    final groupChatRequest = GroupChatRequest(
      sender: userIdInt,
      groupId: targetGroupIdInt,
      message: text,
    );
    logE('sendMessage()-->groupChatRequest:$groupChatRequest');

    final sendContent = '发送：$text';
    final groupChatMessage = ChatMessage(
      type: MessageType.GROUP_CHAT,
      token: '',
      sender: userIdInt,
      receiver: targetGroupIdInt,
      groupId: targetGroupIdInt,
      content: sendContent,
    );
    logE('sendMessage()-->groupChatMessage:$groupChatMessage');

    final groupChatRequestBuffer = groupChatRequest.writeToBuffer();
    logE('sendMessage()-->groupChatRequestBuffer:$groupChatRequestBuffer');

    final groupWrapper = MessageWrapper(
      type: MessageType.GROUP_CHAT,
      payload: groupChatRequestBuffer,
    );

    final groupWrapperBuffer = groupWrapper.writeToBuffer();
    logE('sendMessage()-->groupWrapperBuffer:$groupWrapperBuffer');

    WebSocketServiceProtobuf.to.sendMessage(groupWrapperBuffer);

    sendMessageText = text;

    _addMessage(groupChatMessage);

    editTextController.clear();
  }
}
